package com.lvmama.config.common;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;

import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by troy on 2016/8/29.
 * kouhongyu@163.com
 */
public class ZooKeeperConfigProperties {

    private static final Object LOCK = new Object();
    private static final Object LOCK2 = new Object();

    private static Map<String, BeanField> watcherBeanFieldKeys = new ConcurrentHashMap<String, BeanField>();
    private static Map<String, String> path = new ConcurrentHashMap<String, String>();
    private static Properties properties = new Properties();

    private static ConfigurableListableBeanFactory beanFactory;

    public static void putWatcherBeanField(String key, String beanName, String fieldName, Class<?> classType) throws UnsupportedEncodingException {
        verificationClassType(classType);

        synchronized (LOCK2) {
            BeanField beanField = new BeanField();

            beanField.setBeanName(beanName);
            beanField.setFieldName(fieldName);
            beanField.setClassType(classType);

            watcherBeanFieldKeys.put(key, beanField);

        }
    }

    /**
     * 校验属性类型,只支持简单类型
     *
     * @param classType
     */
    private static void verificationClassType(Class<?> classType) {
        List<Class> clss = new ArrayList<Class>();

        clss.add(Boolean.class);
        clss.add(String.class);
        clss.add(Short.class);
        clss.add(Integer.class);
        clss.add(Long.class);
        clss.add(Float.class);
        clss.add(Double.class);

        if (!clss.contains(classType)) {
            throw new ClassCastException("@ZooKeeperConfigProperty annotation nonsupport " + classType);
        }

    }

    public static void putProperties(String zooKeeperPath, byte[] data) throws UnsupportedEncodingException {

        putProperties(zooKeeperPath, generateKey(zooKeeperPath), new String(data, Constant.UTF_8));

    }

    /**
     * 动态回写加了 {@link com.lvmama.config.annotation.ZooKeeperConfigProperty} 的属性
     *
     * @param zooKeeperPath zooKeeper 的路径
     * @param data          值
     */
    public static void resetBeanField(String zooKeeperPath, byte[] data) throws NoSuchFieldException, UnsupportedEncodingException, IllegalAccessException {
        synchronized (LOCK2) {
            String key = generateKey(zooKeeperPath);
            BeanField beanField = watcherBeanFieldKeys.get(key);

            if (beanField != null) {
                Object bean = beanFactory.getBean(beanField.getBeanName());

                Field field = bean.getClass().getDeclaredField(beanField.getFieldName());

                field.setAccessible(true);

                try {
                    if (Boolean.class.equals(beanField.getClassType())) {
                        field.set(bean, Boolean.valueOf(new String(data, Constant.UTF_8)));

                    } else if (String.class.equals(beanField.getClassType())) {
                        field.set(bean, new String(data, Constant.UTF_8));

                    } else if (Short.class.equals(beanField.getClassType())) {
                        field.set(bean, Short.valueOf(new String(data, Constant.UTF_8)));

                    } else if (Integer.class.equals(beanField.getClassType())) {
                        field.set(bean, Integer.valueOf(new String(data, Constant.UTF_8)));

                    } else if (Long.class.equals(beanField.getClassType())) {
                        field.set(bean, Long.valueOf(new String(data, Constant.UTF_8)));

                    } else if (Float.class.equals(beanField.getClassType())) {
                        field.set(bean, Float.valueOf(new String(data, Constant.UTF_8)));

                    } else if (Double.class.equals(beanField.getClassType())) {
                        field.set(bean, Double.valueOf(new String(data, Constant.UTF_8)));
                    }
                } catch (RuntimeException re) {
                    re.printStackTrace();
                }
                field.setAccessible(false);
            }
        }
    }

    /**
     * 从path 中截取参数key
     *
     * @param zooKeeperPath zooKeeper 的路径
     * @return
     */
    private static String generateKey(String zooKeeperPath) {
        String[] splitPath = zooKeeperPath.split(Constant.SEPARATOR);

        if (splitPath.length >= 5) {
            return splitPath[5];
        }
        return null;
    }

    /**
     * 设置参数
     *
     * @param zooKeeperPath zooKeeper 中的路径
     * @param key           properties 的 key
     * @param value
     */
    public static void putProperties(String zooKeeperPath, String key, String value) {
        synchronized (LOCK) {
            path.put(zooKeeperPath, key);
            properties.put(key, value);
        }
    }

    /**
     * 获取参数
     *
     * @param key key properties 的 key
     * @return
     */
    public static String getProperties(String key) {
        return properties.getProperty(key);
    }


    public static void setBeanFactory(ConfigurableListableBeanFactory factory) {
        beanFactory = factory;
    }
}
